package com.aizuda.boot.modules.business.counterparty.service.impl;


import com.aizuda.boot.modules.business.counterparty.entity.BankInfoEntity;
import com.aizuda.boot.modules.business.counterparty.entity.CounterpartyInfoEntity;
import com.aizuda.boot.modules.business.counterparty.entity.LegalEntityDetailEntity;
import com.aizuda.boot.modules.business.counterparty.entity.dto.CreateBankInfoReqDTO;
import com.aizuda.boot.modules.business.counterparty.entity.vo.CreateBankInfoRespDTO;
import com.aizuda.boot.modules.business.counterparty.mapper.BankInfoMapper;
import com.aizuda.boot.modules.business.counterparty.mapper.CounterpartyInfoMapper;
import com.aizuda.boot.modules.business.counterparty.mapper.LegalEntityDetailMapper;
import com.aizuda.boot.modules.business.counterparty.service.BankInfoService;
import com.aizuda.boot.modules.business.dict.service.CountryDictService;
import com.aizuda.service.web.UserSession;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 银行信息服务实现类
 */
@Slf4j
@Service
public class BankInfoServiceImpl implements BankInfoService {
    
    @Resource
    private BankInfoMapper bankInfoMapper;
    
    @Resource
    private CounterpartyInfoMapper counterpartyInfoMapper;
    
    @Resource
    private LegalEntityDetailMapper legalEntityDetailMapper;
    
    @Resource
    private CountryDictService countryDictService;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CreateBankInfoRespDTO createBankInfo(CreateBankInfoReqDTO reqDTO) {
        // 创建实体对象
        BankInfoEntity entity = new BankInfoEntity();
        
        // 设置基本信息
        entity.setBankCode(reqDTO.getBankCode());
        entity.setBankCountry(reqDTO.getBankCountry());
        entity.setBankName(reqDTO.getBankName());
        entity.setAccountName(reqDTO.getAccountName());
        entity.setAccountNumber(reqDTO.getAccountNumber());
        entity.setBankInternalId(reqDTO.getBankInternalId());
        entity.setCurrency(reqDTO.getCurrency());
        entity.setGeneralLedgerAccount(reqDTO.getGeneralLedgerAccount());
        entity.setClearingAccount(reqDTO.getClearingAccount());
        entity.setAccountAttributeDesc(reqDTO.getAccountAttributeDesc());
        entity.setCreatedAt(LocalDateTime.now());
        entity.setUpdatedAt(LocalDateTime.now());
        
        // 保存到数据库
        int result = bankInfoMapper.insert(entity);
        if (result > 0) {
            log.info("银行信息创建成功，ID: {}, 银行名称: {}, 账号: {}", 
                entity.getId(), entity.getBankName(), entity.getAccountNumber());
            
            // 绑定银行到对应的实体
            bindBankToEntity(reqDTO.getBindingType(), reqDTO.getBindingId(), entity.getId());
            
            // 构造响应DTO
            CreateBankInfoRespDTO respDTO = new CreateBankInfoRespDTO();
            respDTO.setId(entity.getId());
            respDTO.setBankCode(entity.getBankCode());
            
            // 设置银行国家代码和名称
            respDTO.setBankCountryCode(entity.getBankCountry()); // 国家代码
            respDTO.setBankCountry(countryDictService.getCountryNameByCode(entity.getBankCountry())); // 国家名称
            
            respDTO.setBankName(entity.getBankName());
            respDTO.setAccountName(entity.getAccountName());
            respDTO.setAccountNumber(entity.getAccountNumber());
            respDTO.setBankInternalId(entity.getBankInternalId());
            respDTO.setCurrency(entity.getCurrency());
            respDTO.setGeneralLedgerAccount(entity.getGeneralLedgerAccount());
            respDTO.setClearingAccount(entity.getClearingAccount());
            respDTO.setAccountAttributeDesc(entity.getAccountAttributeDesc());
            respDTO.setCreatedAt(entity.getCreatedAt().toString());
            respDTO.setBindingType(reqDTO.getBindingType());
            respDTO.setBindingId(reqDTO.getBindingId());
            
            return respDTO;
        } else {
            throw new RuntimeException("银行信息创建失败");
        }
    }
    
    /**
     * 绑定银行到对应的实体（交易方或法人）
     * @param bindingType 绑定类型
     * @param bindingId 绑定对象ID
     * @param bankId 银行ID
     */
    private void bindBankToEntity(String bindingType, String bindingId, Integer bankId) {
        try {
            Integer entityId = Integer.parseInt(bindingId);
            if ("交易方".equals(bindingType) || "COUNTERPARTY".equals(bindingType)) {
                bindBankToCounterparty(entityId, bankId);
            } else if ("法人".equals(bindingType) || "LEGAL_ENTITY".equals(bindingType)) {
                bindBankToLegalEntity(entityId, bankId);
            } else {
                throw new IllegalArgumentException("不支持的绑定类型: " + bindingType);
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("绑定对象ID格式错误: " + bindingId);
        }
    }
    
    /**
     * 绑定银行到交易方
     * @param counterpartyId 交易方ID
     * @param bankId 银行ID
     */
    private void bindBankToCounterparty(Integer counterpartyId, Integer bankId) {
        CounterpartyInfoEntity counterparty = counterpartyInfoMapper.selectById(counterpartyId);
        if (counterparty == null) {
            throw new RuntimeException("交易方不存在，ID: " + counterpartyId);
        }
        
        // 更新银行ID列表
        String updatedBankIds = addBankIdToList(counterparty.getBankInfoIds(), bankId);

        counterparty.setBankInfoIds(updatedBankIds);
        counterparty.setUpdateBy(UserSession.getLoginInfo().getUsername());
        counterparty.setUpdatedAt(LocalDateTime.now());
        
        int result = counterpartyInfoMapper.updateById(counterparty);
        if (result > 0) {
            log.info("银行信息绑定到交易方成功，交易方ID: {}, 银行ID: {}", counterpartyId, bankId);
        } else {
            throw new RuntimeException("银行信息绑定到交易方失败");
        }
    }
    
    /**
     * 绑定银行到法人
     * @param legalEntityId 法人ID
     * @param bankId 银行ID
     */
    private void bindBankToLegalEntity(Integer legalEntityId, Integer bankId) {
        LegalEntityDetailEntity legalEntity = legalEntityDetailMapper.selectById(legalEntityId);
        if (legalEntity == null) {
            throw new RuntimeException("法人实体不存在，ID: " + legalEntityId);
        }
        
        // 更新银行ID列表
        String updatedBankIds = addBankIdToList(legalEntity.getBankInfoIds(), bankId);

        legalEntity.setBankInfoIds(updatedBankIds);
        legalEntity.setUpdateBy(UserSession.getLoginInfo().getUsername());
        legalEntity.setUpdatedAt(LocalDateTime.now());
        
        int result = legalEntityDetailMapper.updateById(legalEntity);
        if (result > 0) {
            log.info("银行信息绑定到法人成功，法人ID: {}, 银行ID: {}", legalEntityId, bankId);
        } else {
            throw new RuntimeException("银行信息绑定到法人失败");
        }
    }
    
    /**
     * 将银行ID添加到银行ID列表中
     * @param existingBankIds 现有的银行ID列表（逗号分隔）
     * @param newBankId 新的银行ID
     * @return 更新后的银行ID列表
     */
    private String addBankIdToList(String existingBankIds, Integer newBankId) {
        List<String> bankIdList = new ArrayList<>();

        // 解析现有的银行ID列表
        if (existingBankIds != null && !existingBankIds.trim().isEmpty()) {
            bankIdList = Arrays.stream(existingBankIds.split(","))
                    .map(String::trim)
                    .filter(id -> !id.isEmpty())
                    .collect(Collectors.toList());
        }
        
        // 添加新的银行ID（如果不存在）
        String newBankIdStr = newBankId.toString();
        if (!bankIdList.contains(newBankIdStr)) {
            bankIdList.add(newBankIdStr);
        }
        
        return String.join(",", bankIdList);
    }
}